package com.zreal.generator.config;

import com.zreal.generator.codegenerate.database.DataSource;
import com.zreal.generator.util.Constants;
import com.zreal.generator.util.StringUtils;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 处理配置文件
 *
 * @author PJ
 */
public class PropertiesBuilder {
    private static CodeProperties codeProperties;

    public static CodeProperties build(){
        if (codeProperties != null) {
            return codeProperties;
        }
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("code.properties");
        if (inputStream == null) {
            throw new RuntimeException(Constants.ERROR_MSG_NOFILE);
        }
        return build(inputStream);
    }

    public static CodeProperties build(String filePath){
        return build(new File(filePath));
    }

    public static CodeProperties build(File file){
        try {
            return build(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        throw new RuntimeException("未找到配置文件,请检查配置是否正确!");
    }

    public static CodeProperties build(InputStream inputStream){
        if (codeProperties != null) {
            return codeProperties;
        }
        try {
            codeProperties = new CodeProperties();
            Properties properties = new Properties();
            properties.load(inputStream);
            loadCodeProperties(properties);
        } catch (IOException e) {
            System.err.println("未找到配置");
            e.printStackTrace();
        }
        return codeProperties;
    }

    /**
     * 加载配置
     */
    private static void loadCodeProperties(Properties properties) {
        String url = properties.getProperty("dataSource.url");
        String username = properties.getProperty("dataSource.username");
        String password = properties.getProperty("dataSource.password");
        if(StringUtils.isEmpty(url)){
            throw new RuntimeException("未找到配置dataSource.url");
        }
        if(StringUtils.isEmpty(username)){
            throw new RuntimeException("未找到配置dataSource.username");
        }
        DataSource.newInstance(url, username, password);

        String templateDir = getProperty(properties,"templateDir","default");
        String packageName = getProperty(properties,"packageName","com.zreal");
        String ignoreTablePrefix = getProperty(properties,"ignoreTablePrefix","");
        String tableName = properties.getProperty("tableName");
        String targetPath = getProperty(properties,"targetPath", System.getProperty("user.dir"));
        String includeTemplate = getProperty(properties,"includeTemplate","");
        String excludeTemplate = getProperty(properties,"excludeTemplate","");

        // 获取要生成的模板文件
        List<String> templates = new ArrayList<>();
        if(!"default".equals(templateDir)){
            URL dirUrl = Thread.currentThread().getContextClassLoader().getResource("templates/" + templateDir);
            if(dirUrl == null){
                throw new RuntimeException("未找到模板,请检查目录templates/" + templateDir);
            }
            String[] files = new File(dirUrl.getPath()).list();
            templates.addAll(Arrays.asList(files));
        }else{
            String[] templateFiles  = {"Controller.ftl","Entity.ftl","Mapper.ftl","Service.ftl","ServiceImpl.ftl","SqlMapper.ftl"};
            templates.addAll(Arrays.asList(templateFiles));
        }

        // 设置需要生成的模板
        if(!StringUtils.isEmpty(includeTemplate)){
            String[] includeTemplates = includeTemplate.split(",");
            List<String> newTemplates = new ArrayList<>();
            for (int i = 0; i < includeTemplates.length; i++) {
                if(templates.contains(includeTemplates[i])){
                    newTemplates.add(includeTemplates[i]);
                }
            }
            templates = newTemplates;
        }

        // 排除不需要生成的模板
        if(!StringUtils.isEmpty(excludeTemplate)){
            String[] excludeTemplates = excludeTemplate.split(",");
            for (int i = 0; i < excludeTemplates.length; i++) {
                if(templates.contains(excludeTemplates[i])){
                    templates.remove(excludeTemplates[i]);
                }
            }
        }

        codeProperties.setTemplateFiles(templates);
        if(StringUtils.isEmpty(tableName)){
            throw new RuntimeException(Constants.ERROR_MSG_TABLENAME_CAN_NOT_BE_NULL);
        }

        codeProperties.setTemplateDir(templateDir);
        codeProperties.setPackageName(packageName);
        codeProperties.setIgnoreTablePrefix(ignoreTablePrefix);
        codeProperties.setTableName(tableName);
        codeProperties.setTargetPath(targetPath);

    }

    private static String getProperty(Properties properties,String key ,String defaultValue){
        String val = properties.getProperty(key);
        return StringUtils.isEmpty(val) ? defaultValue : val;
    }
}
